package com.dingreading.cloud.soms.service.impl;

import com.dingreading.cloud.common.util.DateUtil;
import com.dingreading.cloud.common.util.NepUtil;
import com.dingreading.cloud.common.util.PageUtil;
import com.dingreading.cloud.common.util.QueryFiledUtil;
import com.dingreading.cloud.soms.dto.MemberCashDto;
import com.dingreading.cloud.soms.entity.MemberCash;
import com.dingreading.cloud.soms.entity.table.MemberCashTableDef;
import com.dingreading.cloud.soms.mapper.MemberCashMapper;
import com.dingreading.cloud.soms.service.MemberCashService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.dingreading.cloud.soms.entity.table.MembersTableDef.members;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2024-07-19
 */
@Service
public class MemberCashServiceImpl extends BaseServiceImpl<MemberCashMapper, MemberCash, MemberCashTableDef> implements MemberCashService {

    @Override
    protected MemberCashTableDef getTable() {
        return MemberCashTableDef.memberCash;
    }

    @Resource
    protected MemberCashMapper memberCashMapper;

    @Override
    public Page<MemberCashDto> pageList(
            PageUtil pageUtil, String corpUid, String storeUid, String keyword, String memberUid, Integer type, String beginDate, String endDate
    ) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (StringUtils.isNotBlank(corpUid))
            condition.and(table.corpUid.eq(corpUid));
        if (StringUtils.isNotBlank(storeUid))
            condition.and(table.storeUid.eq(storeUid));
        if (StringUtils.isNotBlank(memberUid))
            condition.and(table.memberUid.eq(memberUid));
        if (StringUtils.isNotBlank(keyword))
            condition.and(table.memberName.like(keyword)
                    .or(table.storeName.like(keyword))
            );
        if (type != null)
            condition.and(table.type.eq(type));
        if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate))
            condition.and(table.payDate.between(QueryFiledUtil.appendMin00(beginDate), QueryFiledUtil.appendMin24(endDate)));

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.allColumns, members.memberName.as("newMemberName"))
                .from(table)
                .leftJoin(members).on(table.memberUid.eq(members.uid))
                .where(condition)
                .orderBy(table.id.desc());

        return getMapper().paginateAs(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper, MemberCashDto.class);
    }

    private QueryColumn[] getColumns() {
        return new QueryColumn[]{
                table.addTime, table.addStaffUid, table.addStaffName, table.editTime, table.lastStaffUid, table.lastStaffName,
                table.corpUid, table.storeUid, table.storeName, table.memberUid, table.memberName, table.type,
                table.typeName, table.money, table.uid, table.url, table.payDate, members.memberName.as("newMemberName")
        };
    }

    @Override
    public MemberCash getByUid(String storeUid, String uid) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.uid.eq(uid).and(table.storeUid.eq(storeUid)));
        return getMapper().selectOneByQuery(wrapper);
    }

    @Override
    public MemberCashDto dtoByUid(String storeUid, String uid) {
        QueryWrapper wrapper = QueryWrapper.create()
                .select(getColumns())
                .from(table)
                .leftJoin(members).on(table.memberUid.eq(members.uid))
                .where(table.uid.eq(uid).and(table.storeUid.eq(storeUid)));
        return getMapper().selectOneByQueryAs(wrapper, MemberCashDto.class);
    }

    @Override
    public int deleteByUid(String storeUid, String uid) {
        return getMapper().deleteByCondition(table.uid.eq(uid).and(table.storeUid.eq(storeUid)));
    }

    @Override
    public boolean updateInfo(String storeUid, String uid, Double money, String url, String payDate, String staffUid, String staffName) throws ParseException {
        Date date = DateUtil.parseDate(payDate);
        return UpdateChain.of(MemberCash.class)
                .set(table.money, money)
                .set(table.url, url)
                .set(table.payDate, date)
                .set(table.lastStaffUid, NepUtil.nullToZero(staffUid))
                .set(table.lastStaffName, NepUtil.nullToZero(staffName))
                .where(table.uid.eq(uid).and(table.storeUid.eq(storeUid)))
                .update();
    }

    @Override
    public Map<String, Integer> lastByMemberUid(List<String> memberUidList) {
        List<MemberCash> list = memberCashMapper.lastByMemberUid(memberUidList);

        Map<String, Integer> map = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list))
            map = list.stream().collect(Collectors.toMap(MemberCash::getMemberUid, MemberCash::getType));
        return map;
    }
}
